﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Evaluant.Uss.ObjectContext;
using Evaluant.Uss;

namespace NUnit.Mapping.Interfaces
{
    [TestClass]
    public class ExtendedFixture
    {
        protected ObjectContext oc;

        public ExtendedFixture()
        {
            Evaluant.Uss.SqlMapper.SqlMapperProvider provider = new Evaluant.Uss.SqlMapper.SqlMapperProvider();

            provider.ConnectionString = "Server=.;Database=uss;Integrated Security=SSPI";
            provider.Dialect = "Evaluant.Uss.SqlMapper.MsSqlDialect";
            provider.Driver = "Evaluant.Uss.SqlMapper.MsSqlDriver";
            provider.MappingFileName = @"..\..\..\NUnit\Mapping\Interfaces\mapping_2.xml";
            provider.TablePrefix = "INT_";
            provider.RegisterMetaData(MetaDataFactory.FromAssembly(typeof(IItemsHolder).Assembly));

            provider.InitializeConfiguration();

            oc = new ObjectService(provider).CreateObjectContext();
        }

        [TestMethod]
        public void ExtendedInterfaceAndInheritanceRelationTest()
        {
            oc.InitializeRepository();

            Directory d = new Directory();
            d.Name = "Dir";

            DirectoryOverride dov = new DirectoryOverride();
            dov.Name = "Dov";

            StorageItem item = new StorageItem();
            item.Name = "Item of Dir";
            d.Items.Add(item);

            item = new StorageItem();
            item.Name = "Item of Dov";
            dov.Items.Add(item);

            OneMoreItem otheritem = new OneMoreItem();
            otheritem.Name = "The other one";
            dov.Items.Add(otheritem);

            Directory child = new Directory();
            child.Name = "Child of other dir";
            dov.Items.Add(child);

            oc.BeginTransaction();
            oc.Serialize(d);
            oc.Serialize(dov);
            oc.CommitTransaction();

            oc.Clear();

            int subs = oc.Load<IStorageItem>(typeof(IItemsHolder), "[Name ~ 'D'].Items").Count;
            Assert.AreEqual(4, subs);
            oc.Clear();

            subs = oc.LoadSingle<IItemsHolder>("[Name = 'Dov']").Items.Count;
            Assert.AreEqual(3, subs);
            oc.Clear();

            subs = oc.Load<IStorageItem>(typeof(IItemsHolder), ".Items[Name ~ 'other']").Count;
            Assert.AreEqual(2, subs);
            oc.Clear();

            // Here the test is filtering the returned elements
            subs = oc.Load<OneMoreItem>(typeof(IItemsHolder), "[Name ~ 'D'].Items").Count;
            Assert.AreEqual(1, subs);
        }
    }

    public interface IStorageItem
    {
        string Name { get; set; }
    }

    public class OneMoreItem : IStorageItem
    {
        protected string m_Name;
        public string Name
        {
            get { return m_Name; }
            set { m_Name = value; }
        }
    }

    public class StorageItem : IStorageItem
    {
        protected string m_Name;
        public string Name
        {
            get { return m_Name; }
            set { m_Name = value; }
        }
    }

    public class Directory : StorageItem, IItemsHolder
    {
        #region IItemsHolder Members

        protected IList<IStorageItem> m_Items = new List<IStorageItem>();
        public IList<IStorageItem> Items
        {
            get { return m_Items; }
        }

        #endregion
    }

    public class DirectoryOverride : StorageItem, IItemsHolder
    {
        #region IItemsHolder Members

        protected IList<IStorageItem> m_Items = new List<IStorageItem>();
        public IList<IStorageItem> Items
        {
            get { return m_Items; }
        }

        #endregion
    }

    public interface IItemsHolder
    {
        IList<IStorageItem> Items { get; }
    }
}